<?php
/**
 * 客户保有-累计-周期性保有
 */

namespace app\services;

use app\admin\controller\ApiCommon;
use app\crm\logic\WhereLogic;
use app\crm\model\Customer;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

//新的保有计算规则-门店加门诊
class CustomerRetain
{
    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    // 获取累计、周期性保有-流失
    public function baoyou_customer($customer_ids,$today,$shop_id){
        if(empty($customer_ids)){
            return  ['by'=>[],'ls'=>[]];
        }
        $start_time = $this->getlastThreeMonth($today);
        $end_time = strtotime($today);
        $ls = [];
        //先看有没有 收退款、退货
        $public_map = [
            ['deal_time','between',"$start_time,$end_time"],
            ['status','=',2],
            ['shop_id','in',$shop_id]
        ];
        $shop_refund_order_customer_id = DB::name('shop_refund_order')->where($public_map)->column('uid');
        $shop_refund_order_customer_id = array_unique($shop_refund_order_customer_id);
        $shop_refund_order_customer_id_diff = array_diff($customer_ids,$shop_refund_order_customer_id);
        if(!empty($shop_refund_order_customer_id_diff)){
            //再看有没有出货
            $shop_order_customer_id = DB::name('shop_order')->where($public_map)->column('uid');
            $shop_order_customer_id = array_unique($shop_order_customer_id);
            $shop_order_customer_id_diff = array_diff($shop_refund_order_customer_id_diff,$shop_order_customer_id);
            if(!empty($shop_order_customer_id_diff)){
                //再看有没有服务记录
                $where = [
                    ['customer_id','in',$shop_order_customer_id_diff],
                    ['create_time','between',"$start_time,$end_time"],
                    ['is_cancel','<>',2],
                    ['shop_id','in',$shop_id],
                ];
                $service_customer_id = DB::name('service_log')->where($where)->column('customer_id');
                $service_customer_id = array_unique($service_customer_id);
                $service_customer_id_diff = array_diff($shop_order_customer_id_diff,$service_customer_id);
                if(!empty($service_customer_id_diff)){
                    $by = array_diff($customer_ids,$service_customer_id_diff);
                    $ls =  $service_customer_id_diff;
                    return  ['by'=>$by,'ls'=>$ls];
                }
            }
        }
        return  ['by'=>$customer_ids,'ls'=>$ls];
    }


    public function getlastThreeMonth($today){
       return strtotime($today.' -3 month');
    }

    public function getlastOneYear($today){
        return strtotime($today.' -1 year');
    }
    //累计/周期性保有及流失
    public function customerRetainRunoff($cj_customer,$mz_shopids = [],$data = []){
        $today = $data['today'];
        $start_time = $this->getlastThreeMonth($today);
        $end_time = strtotime($today);
        $by_customer = $ls_customer = [];
        if(!empty($cj_customer)){
            foreach($cj_customer as $k=>&$v){
                $cj_service_time = [];
                array_push($cj_service_time,$v['final_service']);
                array_push($cj_service_time,$v['final_cj_time']);
                if(!empty($v['customer'])){
                    $final_service = array_column($v['customer'],'final_service');
                    $final_cj_time= array_column($v['customer'],'final_cj_time');
                    $final_cj_service_time = array_merge($final_cj_time,$final_service);
                    $cj_service_time = array_merge($cj_service_time,$final_cj_service_time);
                }
                rsort($cj_service_time);
                $end_cj_service_time = !empty($cj_service_time[0])?$cj_service_time[0]:0;
                if($start_time<=$end_cj_service_time && $end_cj_service_time <= $end_time){
                    array_push($by_customer,$v['id']);
                }else{
                    array_push($ls_customer,$v['id']);
                }
            }
        }
        return [$by_customer,$ls_customer];

    }
    //获取成交顾客-累计成交/保有
    public function cj_customer($data){

        $public_where = [];
        $cj_time = $data['cj_time']??'';
        if(!empty($cj_time)){
            array_push($public_where,['c.cj_time','=',strtotime($cj_time)]);
        }
        $name = $data['customer_name']??'';
        if(!empty($name)){
            array_push($public_where,['c.customer_name','like',$name."%"]);
        }
        $phone = $data['telephone']??'';
        if(!empty($phone)){
            array_push($public_where,['c.telephone','=',$phone]);
        }
        $member_classification = $data['member_classification']??'';
        if(in_array($member_classification,[70,71,72,73])){
            array_push($public_where,['c.member_classification','=',$member_classification]);
        }
        $shop_id = $data['shop_id']??[];
        if(!empty($shop_id)){
            array_push($public_where,['c.shop_id','=',$shop_id]);
        }

        $shop_ids = $data['shopIds']??[];
        if(!empty($shop_ids)){
            array_push($public_where,['c.shop_id','in',$shop_ids]);
        }

        $last_kftime_start = $data['last_kftime_start'] ?? "";
        $last_kftime_end = $data['last_kftime_end'] ?? "";

        if($last_kftime_start){
            $last_kftime_start1 = strtotime($last_kftime_start);
            array_push($public_where,['c.last_kftime','>=',$last_kftime_start1]);
        }

        if($last_kftime_end){
            $last_kftime_end1 = strtotime($last_kftime_end.' 23:59:59');
            array_push($public_where,['c.last_kftime','<=',$last_kftime_end1]);
        }


        $scar_type_id = $data['scar_type_id']??0;
        if(in_array($scar_type_id,[1,2,3])){
            switch ($scar_type_id){
                case 1:
                    array_push($public_where,['cs.customer_setting_id_type','in',[1,2,3,4,5,6,7,8,655,656]]);
                    break;
                case 2:
                    array_push($public_where,['cs.customer_setting_id_type','=',10]);
                    break;
                case 3:
                    array_push($public_where,['cs.customer_setting_id_type','in',[9,11,12]]);
                    break;
            }
        }
        $scar_id = $data['scar_id'] ?? "";
        if($scar_id){
            array_push($public_where,['cs.customer_setting_id_type','=',$scar_id]);
        }

        $today = $data['today'];

        //默认是累计成交
        $map =[
            ['cj_money','>=',500],
            ['c.final_consumption|c.final_service','>','0'],
        ];
        if($data['by_type']== 2){

            $begin_time = $this->getlastOneYear($today);
            $end_time = strtotime($today);
            //周期性成交
            array_push($map, ['cj_time',"between","$begin_time,$end_time"]);
        }


        $cj_customer_arr = Customer::alias('c')
            ->join('customer_scar cs', 'c.id=cs.customer_id', 'LEFT')
            ->with(['customer'=>function($query)use($map){
            $query->field('telephone,final_service,final_cj_time');
        }])->where($map)->where($public_where)->field('c.id,c.telephone,c.shop_id,c.final_service,c.final_cj_time')->select()->toArray();

        $cj_customer_ids = empty($cj_customer_arr)?[]:array_column($cj_customer_arr,'id');

        return [$cj_customer_arr,$cj_customer_ids];
    }

    //保有门诊
    public function by_mzshop(){
        $map =[
            ['status','=',1],
            ['type','<>','2'],
            ['shop_type','=',1],
        ];
        $mz_shop = DB::name('shop')->where($map)->field('shop_id')->select()->toArray();
        $mz_shop_ids = !empty($mz_shop)?array_column($mz_shop,'shop_id'):[];
        return [$mz_shop,$mz_shop_ids];
    }
    //保有流失客户列表
    public function by_ls_customer_list($data){
        list($cj_customer_arr,$cj_customer_ids) =  $this->cj_customer($data);

        list($by_customer,$ls_customer)  = $this->customerRetainRunoff($cj_customer_arr,[],['today'=>$data['today']]);
        $by_customer = array_unique($by_customer);
        $ls_customer = array_unique($ls_customer);


        $customer = Customer::alias('c')
            ->join('customer_scar cs', 'c.id=cs.customer_id', 'LEFT')
            ->with([
                'shop'=>function($query)use($data){
                    $query->field('shop_id,shop_name');
                },
                'nurse'=>function($query)use($data){
                    $query->field('id,name');
                }]);

        if($data['by_type'] == 1){
            //保有
            $where = [
                ['c.id','in',$by_customer],
            ];
        }else{
            //流失
            $where = [
                ['c.id','in',$ls_customer],
            ];
        }
        $is_export = $data['is_export'] ?? 0;
        $count = $customer->where($where)->group('c.id')->count();

        if($is_export != 1){
            $customer->limit(($data['page'] - 1) * $data['limit'], $data['limit']);
        }
        $list =  $customer->where($where)
            ->field('c.id,c.shop_id,c.customer_name,c.telephone,c.sex,c.first_time,c.second_time,c.create_time,c.source_id,c.nurse_id,c.member_label,c.member_classification,c.consumption,c.cj_time,c.cj_money,c.final_cj_time,c.final_service,c.last_kftime,cs.customer_setting_id_type,c.membership_leve,c.final_consumption,c.age,c.membership_leve')
            ->order('c.id','desc')
            ->group('c.id')
            ->select()
            ->toArray();
        //获取会员等级
        $gradeList = Db::name('customer_grade')->cache(120)->column('name', 'id');
        $settingList    = Db::name('setting')->cache(120)->column('name', 'id');

        if($count >0){
            foreach($list as $k=>&$v){
                $v['cj_time'] = $v['cj_time']?date('Y-m-d',$v['cj_time']):'';

                $v['last_kftime'] = $v['last_kftime']?date('Y-m-d',$v['last_kftime']):'';

                $v['sex'] = $v['sex'] == 1 ? '男':'女';

                $v['age'] = $v['age'] ?? '';

                $v['new_join_shop_time'] = $v['second_time']?date('Y-m-d',$v['second_time']):($v['first_time']?date('Y-m-d',$v['first_time']) : "");

                $v['source_name'] =  $settingList[$v['source_id']] ?? "";

                $v['grade_name'] = $gradeList[$v['membership_leve']] ?? "";

                $v['nurse_name'] = !empty($v['nurse'])?$v['nurse']['name']:'';


                $v['shop_name'] = !empty($v['shop'])?$v['shop']['shopName']:'';

                $v['class_name'] = $settingList[$v['member_classification']] ?? "";

                $v['final_consumption'] = $v['final_consumption']?date('Y-m-d',$v['final_consumption']):'';

                $v['final_service'] = $v['final_service']?date('Y-m-d',$v['final_service']):'';

                $v['consumption'] = $v['consumption'] ?? '';

                $scarIds = explode(',',$v['customer_setting_id_type']);

                $scarName = [];

                foreach ($scarIds as $key => $vv) {

                    $onename = $settingList[$vv] ?? '未知';

                    array_push($scarName,$onename);
                }

                $v['scar_aggregate'] = implode($scarName) ?? "";
            }
        }

        return [$count,$list];
    }

    //订单作废时-使用-最后一次消费及消耗时间
    public function lastServiceConsumeTime($customer_id){

        $mz_service_time = $mz_xf_time =  '';
        $customerData = Customer::where('id',$customer_id)
            ->with(['customer'=>function($query)use($customer_id){
                $query->field('telephone,id');
            }])->field('id,shop_id,telephone')->find();
        if(!empty($customerData)){
            $customerData = $customerData->toArray();
            if(!empty($customerData['customer'])){
                list($mz_shop,$mz_shop_ids)=$this->by_mzshop();
                $public_where = [
                    ['shop_id','in',$mz_shop_ids]
                ];
                $mz_customer_ids = array_column($customerData['customer'],'id');
                $mz_service_time = DB::name('service_log')
                    ->where('is_cancel','<>',2)
                    ->where($public_where)
                    ->whereIn('customer_id',$mz_customer_ids)
                    ->order('create_time','desc')
                    ->value('create_time');
                $public_map = [
                    ['uid','in',$mz_customer_ids],
                    ['status','=',2]
                ];
                $mz_last_cj_time = DB::name('shop_refund_order')
                    ->where($public_map)
                    ->where($public_where)
                    ->order('deal_time','desc')
                    ->value('deal_time');

                $mz_last_cj_order_time = DB::name('shop_order')
                    ->where($public_map)
                    ->where($public_where)
                    ->order('deal_time','desc')
                    ->value('deal_time');
                $mz_cj_time =[];
                if(!empty($mz_last_cj_order_time)){
                    array_push($mz_cj_time,$mz_last_cj_order_time);
                }
                if(!empty($mz_last_cj_time)){
                    array_push($mz_cj_time,$mz_last_cj_time);
                }
                rsort($mz_cj_time);
                $mz_cj_time = !empty($mz_cj_time)?$mz_cj_time[0]:'';
            }
        }

        $md_service_time = DB::name('service_log')
            ->where('is_cancel','<>',2)
            ->where('customer_id',$customer_id)
            ->order('create_time','desc')
            ->value('create_time');

        $md_last_xf_time = DB::name('shop_refund_order')
            ->where('status','=',2)
            ->where('uid',$customer_id)
            ->order('create_time','desc')
            ->value('create_time');

        $md_last_xf_order_time = DB::name('shop_order')
            ->where('status','=',2)
            ->where('uid',$customer_id)
            ->order('create_time','desc')
            ->value('create_time');

        $md_last_cj_time = DB::name('shop_refund_order')
            ->where('status','=',2)
            ->where('uid',$customer_id)
            ->order('deal_time','desc')
            ->value('deal_time');

        $md_last_cj_order_time = DB::name('shop_order')
            ->where('status','=',2)
            ->where('uid',$customer_id)
            ->order('deal_time','desc')
            ->value('deal_time');


        $md_xf_time =[];
        if(!empty($md_last_xf_order_time)){
            array_push($md_xf_time,$md_last_xf_order_time);
        }
        if(!empty($md_last_xf_time)){
            array_push($md_xf_time,$md_last_xf_time);
        }
        rsort($md_xf_time);
        $md_xf_time = !empty($md_xf_time)?$md_xf_time[0]:'';

        $md_cj_time =[];
        if(!empty($md_last_cj_time)){
            array_push($md_cj_time,$md_last_cj_time);
        }
        if(!empty($md_last_cj_order_time)){
            array_push($md_cj_time,$md_last_cj_order_time);
        }
        rsort($md_cj_time);
        $md_cj_time = !empty($md_cj_time)?$md_cj_time[0]:'';

        return [$md_service_time,$md_xf_time,$md_cj_time,$mz_service_time,$mz_cj_time];
    }



}
